package com.example.readcard;

import com.bland.IDReader;
import jakarta.annotation.PostConstruct;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Service;

import java.util.Base64;

import java.io.*;

@Service
public class demo{

    static public String race_table[][] ={
        {"01","汉族"},//   GB/T 3304-1991","Han","HA
        {"02","蒙古族"},//   GB/T 3304-1991","Mongol","MG
        {"03","回族"},//   GB/T 3304-1991","Hui","HU
        {"04","藏族"},//   GB/T 3304-1991","Zang","ZA
        {"05","维吾尔族"},//   GB/T 3304-1991","Uygur","uG
        {"06","苗族"},//   GB/T 3304-1991","Miao","MH
        {"07","彝族"},//   GB/T 3304-1991","Yi","YI
        {"08","壮族"},//   GB/T 3304-1991","Zhuang","ZH
        {"09","布依族"},//   GB/T 3304-1991","Buyei","BY
        {"10","朝鲜族"},//   GB/T 3304-1991","Chosen","cs
        {"11","满族"},//   GB/T 3304-1991","Man","MA
        {"12","侗族"},//   GB/T 3304-1991","Dong","DO
        {"13","瑶族"},//   GB/T 3304-1991","Yao","YA
        {"14","白族"},//   GB/T 3304-1991","Bai","BA
        {"15","土家族"},//   GB/T 3304-1991","Tujia","TJ
        {"16","哈尼族"},//   GB/T 3304-1991","Hani","HN
        {"17","哈萨克族"},//   GB/T 3304-1991","Kazak","KZ
        {"18","傣族"},//   GB/T 3304-1991","Dai","DA
        {"19","黎族"},//   GB/T 3304-1991","Li","LI
        {"20","傈僳族"},//   GB/T 3304-1991","Lisu","LS
        {"21","佤族"},//   GB/T 3304-1991","Va","VA
        {"22","畲族"},//   GB/T 3304-1991","She","SH
        {"23","高山族"},//   GB/T 3304-1991","Gaoshan","Gs
        {"24","拉枯族"},//   GB/T 3304-1991","Lahu","LH
        {"25","水族"},//   GB/T 3304-1991","Sui","su
        {"26","东乡族"},//   GB/T 3304-1991","Dongxiang","DX
        {"27","纳西族"},//   GB/T 3304-1991","Naxi","NX
        {"28","景颇族"},//   GB/T 3304-1991","Jingpo","JP
        {"29","柯尔克孜族"},//   GB/T 3304-1991","Kirgiz","KG
        {"30","土族"},//   GB/T 3304-1991","Tu","TU
        {"31","达斡尔族"},//   GB/T 3304-1991","Daur","DU
        {"32","仫佬族"},//   GB/T 3304-1991","Mulao","ML
        {"33","羌族"},//   GB/T 3304-1991","Qiang","QI
        {"34","布朗族"},//   GB/T 3304-1991","Blang","BL
        {"35","撒拉族"},//   GB/T 3304-1991","Salar","SL
        {"36","毛南族"},//   GB/T 3304-1991","Maonan","MN
        {"37","仡佬族"},//   GB/T 3304-1991","Gelao","GL
        {"38","锡伯族"},//   GB/T 3304-1991","Xibe","XB
        {"39","阿昌族"},//   GB/T 3304-1991","Achang","AC
        {"40","普米族"},//   GB/T 3304-1991","Pumi","PM
        {"41","塔吉克族"},//   GB/T 3304-1991","Tajik","TA
        {"42","怒族"},//   GB/T 3304-1991","Nu","NU
        {"43","乌孜别克族"},//   GB/T 3304-1991","Uzbek","Uz
        {"44","俄罗斯族"},//   GB/T 3304-1991","Russ","RS
        {"45","鄂温克族"},//   GB/T 3304-1991","Ewenki","EW
        {"46","德昂族"},//   GB/T 3304-1991","Deang","DE
        {"47","保安族"},//   GB/T 3304-1991","Bonan","BN
        {"48","裕固族"},//   GB/T 3304-1991","Yugur","YG
        {"49","京族"},//   GB/T 3304-1991","Gin","GI
        {"50","塔塔尔族"},//   GB/T 3304-1991","Tatar","TT
        {"51","独龙族"},//   GB/T 3304-1991","Derung","DR
        {"52","鄂伦春族"},//   GB/T 3304-1991","Oroqen","OR
        {"53","赫哲族"},//   GB/T 3304-1991","Hezhen","HZ
        {"54","门巴族"},//   GB/T 3304-1991","Monba","MB
        {"55","珞巴族"},//   GB/T 3304-1991","Lhoba","LB
        {"56","基诺族"},//   GB/T 3304-1991","Jino","JN
        {"",""}
    };

    /**
     * 将民族代码，转换成文本
     * @param code
     * @return
     */
    public static String GetRace(String code) {
        int i;
        for (i = 0; i < race_table.length; i++) {
            if (race_table[i][0].compareTo(code) == 0) {
                return race_table[i][1];
            }
        }
        return "其它";
    }

    /**
     * 显示身份证信息
     * @param text 文本
     * @param image 照片
     */
    public static void ViewInfo(String text,byte[] image) {
        System.out.println(text);
		try
		{
			File imgFile = new File("image.jpg");
			FileOutputStream writer = new FileOutputStream(imgFile);
			writer.write(image);
			writer.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
    }


    /**
     * 解析SN
     * @param str JSON 格式字符串
     * @return 返回错误或成功信息
     */
    public static int ParseSN(String str) {
        byte[] img;
        String info = "";

        try {
            JSONObject jsondata = new JSONObject(str);

            if(jsondata.has("errorMsg")) {
				//System.out.println(jsondata.getString("errorMsg"));
                return -1;
            }

            if( !jsondata.has("data") ) {
                return -1;
            }

            JSONObject content = jsondata.getJSONObject("data");

			System.out.println("SAM ID: " + content.getString("samid"));
			if(content.has("sn")) {
				System.out.println("SN: " + content.getString("sn"));
			}
		}
		catch (Exception e) {
			e.printStackTrace();
            return -1;
        }
		return 0;
	}

    /**
     * 解析身份证读卡结果
     * @param str JSON 格式字符串
     * @return 返回错误或成功信息
     */
    public static String ParseIDInfo(String str) {
        byte[] img;
        String info = "";

        try {
            JSONObject jsondata = new JSONObject(str);

            if(jsondata.getString("function").compareTo("readcard") != 0) {
                return "";//不是读卡消息，直接返回
            }

            if(jsondata.has("errorMsg")) {
				System.out.println(jsondata.getString("errorMsg"));
                return jsondata.getString("errorMsg");
            }

            if( !jsondata.has("data") ) {
                return "";
            }

            JSONObject content = jsondata.getJSONObject("data");

			if(content.getString("type").compareTo("I") == 0) {
				info = "外国人永久居留证";
			}
			else if(content.getString("type").compareTo("J") == 0) {
				info = "港澳台居住证";
			}
			else if(content.getString("type").compareTo(" ") == 0) {
				info = "居民身份证";
			}
			else  {
				info = "未知";
			}

            info = info + "\r\n姓名：" + content.getString("name");
            info = info + "\r\n身份证号：" + content.getString("number");
            String gender;
            if(content.getInt("gender") == 1) {
                gender = "男";
            }
            else if (content.getInt("gender") == 2){
                gender = "女";
            }
            else {
                gender = "未知";
            }
            info = info + "\r\n性别： " + gender;

			if(content.getString("type").compareTo(" ") == 0) {
				//只有身份证有民族信息
	            info = info + "\r\n民族： " + GetRace(content.getString("race"));
			}

            info = info + "\r\n生日： " + content.getString("birthday");

			if(content.getString("type").compareTo("I") != 0 ) {
				//外国人永久居留证没有住址信息
	            info = info + "\r\n住址： " + content.getString("address");
			}

            info = info + "\r\n签发机关： " + content.getString("issuer");
            info = info + "\r\n有效期限： " + content.getString("valied") + "-" + content.getString("expire");

			if(content.getString("type").compareTo("I") == 0) {
				//外国人永久居留证
	            info = info + "\r\n中文名称： " + content.getString("cn_name");
				info = info + "\r\n版本： " + content.getString("version");
				info = info + "\r\n国籍： " + content.getString("nation");
			}
			else if(content.getString("type").compareTo("J") == 0) {
				//港澳台居住证
	            info = info + "\r\n通行证号码： " + content.getString("pass_number");
				info = info + "\r\n签发次数： " + content.getString("issue_count");
			}

			info = info + "\r\n";

            img = Base64.getDecoder().decode(content.getString("photo"));
			ViewInfo(info,img);
            return "读卡成功！";
        }
        catch (Exception e) {
			e.printStackTrace();
            return e.getMessage();
        }

    }

    /**
     * 解析银行卡读卡结果
     * @param str JSON 格式字符串
     * @return 返回错误或成功信息
     */
    public static String ParseBankInfo(String str) {
        byte[] img;
        String info = "";

        try {
            JSONObject jsondata = new JSONObject(str);

            if(jsondata.has("errorMsg")) {
				System.out.println(jsondata.getString("errorMsg"));
                return jsondata.getString("errorMsg");
            }

            if( !jsondata.has("data") ) {
                return "";
            }

            JSONObject content = jsondata.getJSONObject("data");


            info = info + "\r\n银行卡号：" + content.getString("number");
            info = info + "\r\n有效期截止： " + content.getString("expire");

            info = info + "\r\n持卡人：" + content.getString("owner");
            info = info + "\r\n持卡人证件号码： " + content.getString("owner_id");

			info = info + "\r\n";

			System.out.println(info);

            return "读卡成功！";
        }
        catch (Exception e) {
			e.printStackTrace();
            return e.getMessage();
        }

	}

    /**
     * 解析读卡结果的返回值
     * @param str JSON 格式字符串
     * @return 返回读卡结果的返回值
     */
	public static int GetRetValue(String str) {
        try {
            JSONObject jsondata = new JSONObject(str);
			if(jsondata.has("ret")) {
				return jsondata.getInt("ret");
			}
			else {
				return -1;
			}
		}
        catch (Exception e) {
			e.printStackTrace();
            return -1;
        }
	}

	@PostConstruct
	public void readCard() {
		String systemType = System.getProperty("os.name");
		String systemArch = System.getProperty("os.arch");

		IDReader reader = new IDReader();

		System.out.println("System Type: " + systemType + ", " + systemArch);

		//提供一个可读写的目录，用于初始化过程中读写配置，解压调用库文件。初始化只能调用一次。

		reader.Init("./res");
		System.out.println("demo start!");

		try
		{
			while(true) {
				Thread.sleep(100);
				String result = reader.WebSocketAPI("{\"module\":\"idcard\",\"msgid\":\"0\",\"function\":\"getsam\"}");
				if(ParseSN(result) == 0) {
					break;
				}
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		try
		{

			while(true) {
				String result;

				result = reader.WebSocketAPI("{\"module\":\"idcard\",\"msgid\":\"0\",\"function\":\"readcard\"}");
				if( GetRetValue(result) == 0) {
					ParseIDInfo(result);
					Thread.sleep(1000);
					continue;
				}

				result = reader.WebSocketAPI("{\"module\":\"iccard\",\"msgid\":\"0\",\"function\":\"iso14443a_find\"}");
				if( GetRetValue(result) == 0) {
					//读银行卡号码
					result = reader.WebSocketAPI("{\"module\":\"iccard\",\"msgid\":\"0\",\"function\":\"pboc_read\"}");
					ParseBankInfo(result);
					Thread.sleep(1000);
					continue;
				}
				Thread.sleep(100);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}


	}
}

